Skip to content

Conversation

@baptmont
Copy link
Contributor

For #4
Supersedes #6
Added draft-7 conformance tests, including format.json which is ignored for draft 2020.
Added Draft to resolved.
When marshaling, kept @slimslenderslacks logic to use prefix items + items. Added logic to separate dependencies field, separate id behavior into id and anchor, replace Ref to items.
When resolving and validating ignore other properties of ref objects

// - https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01
// - https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01
// It supports both draft-07 and the 2020-12 draft specifications:
// - Draft-07: http://json-schema.org/draft-07/schema#
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref string `json:"$ref,omitempty"`
Comment string `json:"$comment,omitempty"`
Defs map[string]*Schema `json:"$defs,omitempty"`
// definitions is deprecated but still allowed. It is a synonym for $defs.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not deprecated in draft7

Definitions map[string]*Schema `json:"definitions,omitempty"`

// store dependencies value to use when resolving draft
Dependencies map[string]json.RawMessage `json:"dependencies,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be map[string]any instead?

}
}

// type: https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-6.1.1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where Dependencies is validated.

typ = s.Types
}

// For draft-07 compatibility: if we only have PrefixItems and no Items,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't is possible in draft2020-12 to have PrefixItems but no Items?

}

func newResolved(s *Schema) *Resolved {
type Draft int
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexport this and the DraftXXX values until we're sure that users need them.

}

// DetectDraft inspects the raw JSON to determine the schema version.
func DetectDraft(s *Schema) Draft {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unexport

// 1. Check explicit $schema declaration (The Gold Standard)
if s.Schema != "" {
if strings.Contains(s.Schema, "draft-07") ||
strings.Contains(s.Schema, "draft-06") ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are draft-06 and draft-04 here?

return Draft7
}
if strings.Contains(s.Schema, "2020-12") ||
strings.Contains(s.Schema, "2019-09") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is 2019-09 here?

}
}

// If $schema is missing, look for structural clues
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just default to 2020-12? Is there a good reason to guess? It seems a bit magical and error-prone.

//
// [JSON Schema specification]: https://json-schema.org/understanding-json-schema/reference/annotations
ValidateDefaults bool
Draft *Draft
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user can just set Schema.Schema.

// TODO(jba): consider arrays of structs.
if instance.Kind() == reflect.Array || instance.Kind() == reflect.Slice {
// Handle both draft-07 and draft 2020-12 array validation using the same logic
// Draft-07 items arrays are converted to prefixItems during unmarshaling
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But maybe this Schema wasn't unmarshaled.

// Note that all the items in this array have been validated.
anns.allItems = true
} else if schema.AdditionalItems != nil {
// Draft-07 style: use additionalItems for remaining items
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide on the draft based on the presence/absence of fields, then resolve should check the schema draft against these fields. For example, it should be an error if AdditionalItems appears in a 2020-12 schema, or PrefixItems appears in a draft07 one.

return nil
}

func (s *Schema) normalizeDraft7(items json.RawMessage) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on what's happening here. It seems that fields of the Schema are being changed and moved around. I don't think that's a good idea. We should marshal what the user gave us without changing it, so when it's unmarshaled it looks the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants